<template>
  <el-form
    :model="ruleForm"
    ref="ruleForm"
    style="width: 100%"
    label-width="0px"
  >
    <el-table :data="localDataSource" border>
      <el-table-column fixed="left" type="index" width="60"> </el-table-column>
      <el-table-column
        v-for="(item, index) in columns"
        :key="index"
        :fixed="item.fixed"
        v-bind="$attrs"
        :width="item.width"
      >
        <template slot="header" slot-scope="scope">
          <div class="table-header">
            <span>{{ item.label }}</span>
            <template v-if="item.type && !item.hideHeaderType">
              <el-input
                v-if="item.type === 'input'"
                v-model="ruleForm[item.prop]"
                :placeholder="`请输入${item.label}`"
                @change="handleSelect(item.prop)"
                clearable
              />
              <el-input
                v-if="item.type === 'input-number'"
                type="number"
                v-model.number="ruleForm[item.prop]"
                :placeholder="`请输入${item.label}`"
                @change="handleSelect(item.prop)"
                clearable
              />
              <el-select
                v-if="item.type === 'select'"
                v-model="ruleForm[item.prop]"
                @change="handleSelect(item.prop)"
                style="width: 200px"
                :placeholder="`请选择${item.label}`"
                :multiple="item.formProps && item.formProps.multiple"
                clearable
              >
                <el-option
                  v-for="(list, index) in item.dataSource"
                  :key="index"
                  :label="list.label"
                  :value="list.value"
                >
                </el-option>
              </el-select>
              <el-radio-group
                v-if="item.type === 'radio'"
                v-model="ruleForm[item.prop]"
                @change="handleSelect(item.prop)"
              >
                <el-radio
                  v-for="list in item.dataSource"
                  :key="list.value"
                  :label="list.value"
                  >{{ list.label }}</el-radio
                >
              </el-radio-group>
              <el-date-picker
                v-model="ruleForm[item.prop]"
                v-if="item.type === 'datePicker'"
                type="datetime"
                style="width: 220px"
                :placeholder="`请选择${item.label}`"
                value-format="yyyy-MM-dd HH:mm:ss"
                :picker-options="item.pickerOptions || {}"
                @change="handleSelect(item.prop)"
                clearable
              />
            </template>
          </div>
        </template>
        <template #default="{ row, $index }">
          <el-form-item
            :prop="`columnList.${$index}.${item.prop}`"
            :rules="item.required || item.validator ? getRule(item) : []"
            v-if="
              item.type &&
              (item.linkageFn
                ? item.linkageFn(ruleForm.columnList[$index])
                : true)
            "
          >
            <el-input
              v-if="item.type === 'input'"
              v-model="ruleForm.columnList[$index][item.prop]"
              style="width: 200px"
              :placeholder="`请输入${item.label}`"
              clearable
            />
            <el-input
              v-if="item.type === 'input-number'"
              v-model.number="ruleForm.columnList[$index][item.prop]"
              type="number"
              style="width: 200px"
              :placeholder="`请输入${item.label}`"
              clearable
            />
            <el-select
              v-if="item.type === 'select'"
              v-model="ruleForm.columnList[$index][item.prop]"
              :multiple="item.formProps && item.formProps.multiple"
              style="width: 200px"
              :placeholder="`请选择${item.label}`"
              clearable
            >
              <el-option
                v-for="(item, index) in item.dataSource"
                :key="index"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
            <el-radio-group
              v-if="item.type === 'radio'"
              v-model="ruleForm.columnList[$index][item.prop]"
            >
              <el-radio
                v-for="list in item.dataSource"
                :key="list.value"
                :label="list.value"
                >{{ list.label }}</el-radio
              >
            </el-radio-group>
            <el-date-picker
              v-model="ruleForm.columnList[$index][item.prop]"
              v-if="item.type === 'datePicker'"
              type="datetime"
              style="width: 220px"
              :placeholder="`请选择${item.label}`"
              value-format="yyyy-MM-dd HH:mm:ss"
              :picker-options="item.pickerOptions || {}"
              clearable
            />
          </el-form-item>
          <template v-else-if="item.slotFn">{{ item.slotFn(row) }}</template>
          <span v-else-if="item.dictType">{{
            row[item.prop] | dictFilter(item.dictType)
          }}</span>
          <span v-else-if="!item.type">{{ row[item.prop] }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button size="mini" @click="handleDel(scope.$index)"
            >移除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
  </el-form>
</template>

<script>
import { cloneDeep } from "lodash";
export default {
  data() {
    return {
      localDataSource: [],
      columns: [],
      ruleForm: {
        columnList: [],
      },
    };
  },
  methods: {
    init(data, columns) {
      this.ruleForm.columnList = [];
      columns.forEach((i) => {
        this.$set(this.ruleForm, i.prop, i.defaultValue ?? "");
      });
      this.localDataSource = data.map((i) => {
        return {
          ...this.ruleForm,
          ...i,
        };
      });
      this.localDataSource.forEach((i) => {
        const props = columns.map((j) => j.prop);
        columns.forEach((j) => {
          if (j.dataSourceInRow) {
            j.dataSource = j.dataSourceInRow(i);
          }
        });
        const obj = props.reduce((p, v) => {
          return (p[v] = i[v]) ?? "", p;
        }, {});
        this.ruleForm.columnList.push(obj);
      });
      this.columns = columns.map((i) => {
        if (i.dictType && !i.dataSource) {
          i.dataSource = this.getDict([i.dictType]);
        }

        if (!i.formProps && i.type) {
          this.$set(i, "formProps", {});
        }
        return i;
      });
    },
    getRule(item) {
      const trigger = item.type === "input" ? "blur" : "change";
      const rule = {
        required: item.required,
        message: `请输入${item.label}`,
        trigger,
      };
      if (item.validator) {
        rule.validator = item.validator;
        delete rule.message;
      }
      return [rule];
    },
    validate() {
      return new Promise((resolve) => {
        this.$refs.ruleForm.validate((valid) => {
          resolve(valid);
        });
      });
    },
    getData() {
      return this.ruleForm.columnList.map((i, index) => {
        return {
          ...this.localDataSource[index],
          ...i,
        };
      });
    },
    handleSelect(val) {
      this.ruleForm.columnList.forEach((i) => {
        i[val] = cloneDeep(this.ruleForm[val]);
      });
    },
    handleDel(i) {
      this.ruleForm.columnList.splice(i, 1);
      this.localDataSource.splice(i, 1);
    },
  },
};
</script>
<style lang="scss" scoped>
// @import "~@/style/modal.scss";
.table-header {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
</style>
